#include "msgproto.h"

msgproto::msgproto()
{

}

bool msgproto::in(char *buf, int size, int &cmd)
{
    proto_hdr_t *hdr;
    uint16_t len;
    uint16_t *sum;

    hdr = (proto_hdr_t*)buf;

    if (hdr->start != 0x01EF)
        return false;

    len = swap(hdr->len);
    if (size < (len + 9))
        return false;

    sum = (uint16_t*)((uint32_t)buf + len + 7);
    if (chksum(&hdr->type, len + 1) != *sum)
        return false;

    cmd = hdr->cmd;

    return true;
}

QByteArray msgproto::makeDoorCtrl(uint8_t op)
{
    QByteArray buf(sizeof(doorctrl_req_t), 0);
    doorctrl_req_t *req;

    req = (doorctrl_req_t *)buf.data();

    cmd_hdrinit(buf, MP_CMD_DOOR, 4);
    req->op = op;
    req->sum = chksum(&req->hdr.type, sizeof(*req) - 8);

    return buf;
}

QByteArray msgproto::makeLightCtrl(uint8_t op)
{
    QByteArray buf(sizeof(doorctrl_req_t), 0);
    doorctrl_req_t *req;

    req = (doorctrl_req_t *)buf.data();

    cmd_hdrinit(buf, MP_CMD_LTCTL, 4);
    req->op = op;
    req->sum = chksum(&req->hdr.type, sizeof(*req) - 8);

    return buf;
}

QByteArray msgproto::makeSwitchVal(uint8_t ch)
{
    QByteArray buf(sizeof(swv_req_t), 0);
    swv_req_t *req;

    req = (swv_req_t *)buf.data();

    cmd_hdrinit(buf, MP_CMD_SWV, 4);
    req->ch = ch;
    req->sum = chksum(&req->hdr.type, sizeof(*req) - 8);

    return buf;
}

QByteArray msgproto::makeRelaySpare(uint8_t ch, uint8_t op)
{
    QByteArray buf(sizeof(relays_req_t), 0);
    relays_req_t *req;

    req = (relays_req_t *)buf.data();

    cmd_hdrinit(buf, MP_CMD_RLCTL, 5);
    req->ch = ch;
    req->op = op;
    req->sum = chksum(&req->hdr.type, sizeof(*req) - 8);

    return buf;
}

uint16_t msgproto::chksum(uint8_t *data, int size)
{
    uint16_t sum = 0;

    for (int i = 0; i < size; i ++)
    {
        sum += data[i];
    }

    return swap(sum);
}

uint16_t msgproto::swap(uint16_t v)
{
    return ((v >> 8) | (v << 8));
}

void msgproto::cmd_hdrinit(QByteArray &buf, uint8_t cmd, uint16_t len)
{
    proto_hdr_t *hdr;

    hdr = (proto_hdr_t *)buf.data();

    hdr->start = swap(MP_START);
    hdr->addr = 0xFFFFFFFF;
    hdr->type = 1;
    hdr->cmd = cmd;
    hdr->len = swap(len);
}
